package com.jy.print.javaprint.utils;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.printing.Printer;
import org.eclipse.swt.printing.PrinterData;

import java.awt.image.BufferedImage;
import java.util.Hashtable;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.Result;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

/**
 * 二维码打印
 */
public class QrCodePrint {

    private String qrCode;
    private boolean printerFinish;
    private Printer printer;
    private Font font;
    private Font font1;
    private Color foregroundColor, backgroundColor;
    private GC gc;
    private int lineHeight = 0;
    private Point dpi;
    private static final String CHARSET = "utf-8";
    // 二维码尺寸
    private static final int QRCODE_SIZE = 300;

    private int x, y;

    public QrCodePrint(String qrCode) {
        this.qrCode = qrCode;
    }

    public void doPrint() {
        PrinterData[] printerList = Printer.getPrinterList();
        String printName = "Deli DL-888D";
        for (int i = 0; i < printerList.length; i++) {
            if (printerList[i].name.equals(printName)) {
                printerFinish = false;
                printerList[i].copyCount = 1;
                printer = new Printer(printerList[i]);
                Thread printingThread = new Thread("Printing") {
                    public void run() {
                        try {
                            try {
                                print(printer);
                                printer.dispose();
                            } finally {
                                printerFinish = true;
                                synchronized (this) {
                                    this.notifyAll();
                                }
                            }
                        } catch (Exception e) {
                            System.out.println(e.getMessage());
                        } catch (Throwable e) {
                            System.out.println(e.getMessage());
                        }
                    }
                };
                printingThread.start();
                break;
            }
        }
    }


    void print(Printer printer) {
        if (printer.startJob("Text")) { // the string is the job name - shows up in the printer's job list
            dpi = printer.getDPI();

            gc = new GC(printer);
            try {
                try {
                    font = new Font(printer, "宋体", 8, SWT.BOLD);
                    font1 = new Font(printer, "宋体", 7, SWT.BOLD);
                    foregroundColor = printer.getSystemColor(SWT.COLOR_BLACK);
                    backgroundColor = printer.getSystemColor(SWT.COLOR_WHITE);

                    gc.setFont(font);
                    lineHeight = gc.getFontMetrics().getHeight() + 2;
                    gc.setForeground(foregroundColor);
                    gc.setBackground(backgroundColor);

                    printContent();

                    printer.endJob();
                } finally {
                    if (font != null) {
                        font.dispose();
                        font = null;
                    }
                    if (font1 != null) {
                        font1.dispose();
                        font1 = null;
                    }
                    if (foregroundColor != null) {
                        foregroundColor.dispose();
                        foregroundColor = null;
                    }
                    if (backgroundColor != null) {
                        backgroundColor.dispose();
                        backgroundColor = null;
                    }
                }
            } finally {
                gc.dispose();
            }
        }
    }

    void printContent() {
        int linespace = 10;//(int) ((1d * dpi.y) / 25.4d) ;
        int left = 20;//(int) (rightMargin - (66d * dpi.x) / 25.4d);

        printer.startPage();
        printGd(linespace, left);
        printer.endPage();
    }


    private void printGd(int linespace, int left) {
        gc.setFont(font);

        y = 20;
        x = left;
        int wordWidth = gc.stringExtent(qrCode).x;
        gc.drawString(qrCode, x + 60, y + 5, false);

        x = left;
        y += lineHeight;
        y += linespace;
        try {

            int destWidth = (int) ((25d * dpi.x) / 25.4d);
            int destHeight = (int) (25d * dpi.y / 25.4d);
            BufferedImage bImage = this.createImage();
            ImageData imageData = BufImgToMat.getImageData(bImage);
            Image image = new Image(printer, imageData);
            try {
                int vw = imageData.width;
                int vh = imageData.height;

                int destX = x + 55;
                int destY = y - 5 ;
                gc.drawImage(image, 0, 0, vw, vh, destX, destY, destWidth, destHeight);

            } finally {
                image.dispose();
            }
        } catch (Exception localException) {
            localException.printStackTrace();
        }

    }



    private BufferedImage createImage() throws Exception {
        Hashtable hints = new Hashtable();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
        hints.put(EncodeHintType.MARGIN, 1);
        BitMatrix bitMatrix = new MultiFormatWriter().encode(qrCode, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE,
                hints);
        int width = bitMatrix.getWidth();
        int height = bitMatrix.getHeight();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
            }
        }
        return image;
    }


}
